package com.smart.community.property.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smart.community.commons.cache.DataScopeInfo;
import com.smart.community.commons.entity.property.PropertyCompanyCommunity;
import com.smart.community.commons.entity.property.UserPropertyCompany;
import com.smart.community.commons.enums.RoleCodeEnum;
import com.smart.community.commons.utils.SecurityUtils;
import com.smart.community.feign.region.dto.CommunityInfoDTO;
import com.smart.community.feign.region.dto.OwnerInfoDTO;
import com.smart.community.feign.region.service.OwnerFeignService;
import com.smart.community.feign.region.service.RegionAddressFeignService;
import com.smart.community.feign.user.dto.RoleDTO;
import com.smart.community.feign.user.dto.UserDTO;
import com.smart.community.feign.user.service.UserFeignService;
import com.smart.community.property.enums.DataScope;
import com.smart.community.property.exception.DataScopeException;
import com.smart.community.property.mapper.PropertyCompanyCommunityMapper;
import com.smart.community.property.mapper.UserPropertyCompanyMapper;
import com.smart.community.property.service.DataScopeService;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 数据权限控制服务实现类
 * 
 * 生产环境高标准优化版本：
 * 1. 缓存策略优化：统一缓存键命名、合理过期时间、缓存降级机制
 * 2. 性能优化：批量操作、连接池优化、异步处理
 * 3. 异常处理：完善的异常处理和日志记录
 * 4. 监控告警：缓存命中率、响应时间监控
 * 5. 数据一致性：缓存更新策略、数据同步机制
 * 
 * @author Wu.Liang
 * @since 2025-07-01
 * @version 2.0.0 - 生产环境高标准优化版本
 */
@Slf4j
@Service
public class DataScopeServiceImpl extends ServiceImpl<UserPropertyCompanyMapper, UserPropertyCompany> implements DataScopeService {
    
    // =============== 缓存配置常量（生产环境优化） ===============
    
    /**
     * 缓存键前缀 - 统一命名规范：模块:业务:类型:标识符
     */
    private static final String CACHE_KEY_PREFIX = "property:datascope:user:";
    
    /**
     * 缓存过期时间配置 - 根据业务特点设置合理时间
     */
    private static final long DATA_SCOPE_CACHE_EXPIRE = 30; // 数据权限缓存30分钟
    private static final long USER_ROLES_CACHE_EXPIRE = 15; // 用户角色缓存15分钟
    private static final long HOUSEHOLD_IDS_CACHE_EXPIRE = 25; // 房户ID缓存25分钟
    
    /**
     * 兼容旧接口的缓存常量（逐步迁移）
     */
    private static final String CACHE_PREFIX_NORMAL_USER_SUPER_SUPER_ADMIN = "user:super:admin:";
    private static final String CACHE_PREFIX_NORMAL_USER_DATA_SCOPE = "user:data:scope:";
    private static final String CACHE_PREFIX_NORMAL_USER_PROPERTY_COMPANY_IDS = "user:property:company:ids:";
    private static final String CACHE_PREFIX_NORMAL_USER_COMMUNITY_IDS = "user:community:ids:";
    private static final String CACHE_PREFIX_OWNER_HOUSEHOLD_IDS = "owner:household:ids:";
    
    /**
     * 缓存操作重试次数
     */
    private static final int CACHE_RETRY_TIMES = 3;
    
    // =============== 依赖注入 ===============
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Autowired
    private UserPropertyCompanyMapper userPropertyCompanyMapper;
    
    @Autowired
    private PropertyCompanyCommunityMapper propertyCompanyCommunityMapper;
    
    @Autowired
    private UserFeignService userFeignService;
    
    @Autowired
    private OwnerFeignService ownerFeignService;
    
    @Autowired
    private RegionAddressFeignService regionAddressFeignService;
    
    
    // =============== 核心方法实现（生产环境优化） ===============
    
    @Override
    @Cacheable(value = "dataScope:currentUser", key = "'current'", unless = "#result == null")
    public DataScopeInfo getCurrentUserDataScope() throws Exception {
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            log.error("获取当前用户ID失败，用户未登录或会话已过期");
            throw DataScopeException.userInfoError();
        }
        return getUserDataScope(userId);
    }
    
    @Override
    @Cacheable(value = "dataScope:user", key = "#userId", unless = "#result == null")
    public DataScopeInfo getUserDataScope(Long userId) throws Exception {
        if (userId == null) {
            log.error("用户ID为空，无法获取数据权限信息");
            throw DataScopeException.userInfoError();
        }
        
        // 直接构建数据权限信息，由Spring Cache自动管理缓存
        log.debug("构建用户数据权限信息，用户ID：{}", userId);
        return buildUserDataScope(userId);
    }
    
    /**
     * 从缓存获取数据权限信息（生产环境优化版本）
     * 
     * @param cacheKey 缓存键
     * @return 数据权限信息，如果缓存不存在或异常则返回null
     */
    private DataScopeInfo getCachedDataScope(String cacheKey) {
        for (int i = 0; i < CACHE_RETRY_TIMES; i++) {
            try {
                Object cacheResult = redisTemplate.opsForValue().get(cacheKey);
                
                if (cacheResult == null) {
                    return null;
                }
                
                // 处理不同类型的缓存结果
                if (cacheResult instanceof DataScopeInfo) {
                    return (DataScopeInfo) cacheResult;
                } else if (cacheResult instanceof Map) {
                    // 处理Redis反序列化为LinkedHashMap的情况
                    DataScopeInfo dataScopeInfo = convertMapToDataScopeInfo((Map<String, Object>) cacheResult);
                    if (dataScopeInfo != null) {
                        // 重新缓存正确类型的对象
                        setCachedDataScope(cacheKey, dataScopeInfo);
                        return dataScopeInfo;
                    }
                }
                
                // 缓存数据格式错误，清除缓存
                log.warn("缓存数据格式错误，清除缓存，缓存键：{}", cacheKey);
                redisTemplate.delete(cacheKey);
                return null;
                
            } catch (Exception e) {
                log.warn("缓存获取失败，重试次数：{}/{}，缓存键：{}，错误：{}", 
                    i + 1, CACHE_RETRY_TIMES, cacheKey, e.getMessage());
                
                if (i == CACHE_RETRY_TIMES - 1) {
                    log.error("缓存获取最终失败，缓存键：{}", cacheKey, e);
                }
            }
        }
        return null;
    }
    
    /**
     * 设置缓存数据权限信息（生产环境优化版本）
     * 
     * @param cacheKey 缓存键
     * @param dataScopeInfo 数据权限信息
     */
    private void setCachedDataScope(String cacheKey, DataScopeInfo dataScopeInfo) {
        if (dataScopeInfo == null) {
            log.warn("数据权限信息为空，不进行缓存，缓存键：{}", cacheKey);
            return;
        }
        
        for (int i = 0; i < CACHE_RETRY_TIMES; i++) {
            try {
                redisTemplate.opsForValue().set(cacheKey, dataScopeInfo, DATA_SCOPE_CACHE_EXPIRE, TimeUnit.MINUTES);
                log.debug("数据权限信息缓存成功，缓存键：{}，过期时间：{}分钟", cacheKey, DATA_SCOPE_CACHE_EXPIRE);
                return;
                
            } catch (Exception e) {
                log.warn("缓存设置失败，重试次数：{}/{}，缓存键：{}，错误：{}", 
                    i + 1, CACHE_RETRY_TIMES, cacheKey, e.getMessage());
                
                if (i == CACHE_RETRY_TIMES - 1) {
                    log.error("缓存设置最终失败，缓存键：{}", cacheKey, e);
                }
            }
        }
    }
    
    @Override
    public boolean hasPropertyCompanyPermission(Long userId, Long propertyCompanyId) throws Exception {
        DataScopeInfo dataScopeInfo = getUserDataScope(userId);
        return dataScopeInfo.hasPropertyCompanyPermission(propertyCompanyId);
    }
    
    @Override
    public boolean hasCommunityPermission(Long userId, Long communityId) throws Exception {
        DataScopeInfo dataScopeInfo = getUserDataScope(userId);
        return dataScopeInfo.hasCommunityPermission(communityId);
    }
    
    @Override
    public boolean hasModulePermission(Long userId, String moduleCode) throws Exception {
        DataScopeInfo dataScopeInfo = getUserDataScope(userId);
        return dataScopeInfo.hasModulePermission(moduleCode);
    }
    
    @Override
    public void validateBatchPropertyCompanyPermission(Long userId, List<Long> propertyCompanyIds) throws Exception {
        if (propertyCompanyIds == null || propertyCompanyIds.isEmpty()) {
            return;
        }
        
        DataScopeInfo dataScopeInfo = getUserDataScope(userId);
        if (dataScopeInfo.isSuperAdmin()) {
            return;
        }
        
        for (Long propertyCompanyId : propertyCompanyIds) {
            if (!dataScopeInfo.hasPropertyCompanyPermission(propertyCompanyId)) {
                throw new DataScopeException("用户无权限访问物业公司ID：" + propertyCompanyId);
            }
        }
    }
    
    @Override
    public void validateBatchCommunityPermission(Long userId, List<Long> communityIds) throws Exception {
        if (communityIds == null || communityIds.isEmpty()) {
            return;
        }
        
        DataScopeInfo dataScopeInfo = getUserDataScope(userId);
        if (dataScopeInfo.isSuperAdmin()) {
            return;
        }
        
        for (Long communityId : communityIds) {
            if (!dataScopeInfo.hasCommunityPermission(communityId)) {
                throw new DataScopeException("用户无权限访问社区ID：" + communityId);
            }
        }
    }
    
    @Override
    public void clearUserPermissionCache(Long userId) throws Exception {
        if (userId == null) {
            userId = SecurityUtils.getCurrentUserId();
        }
        
        if (userId == null) {
            log.warn("用户ID为空，无法清除权限缓存");
            return;
        }
        
        try {
            // 构建所有需要清除的缓存键
            String[] cacheKeys = {
                CACHE_KEY_PREFIX + userId,
                CACHE_PREFIX_NORMAL_USER_DATA_SCOPE + userId,
                CACHE_PREFIX_NORMAL_USER_PROPERTY_COMPANY_IDS + userId,
                CACHE_PREFIX_NORMAL_USER_COMMUNITY_IDS + userId,
                CACHE_PREFIX_NORMAL_USER_SUPER_SUPER_ADMIN + userId,
                CACHE_PREFIX_OWNER_HOUSEHOLD_IDS + userId
            };
            
            // 批量删除缓存
            int deletedCount = 0;
            for (String cacheKey : cacheKeys) {
                try {
                    Boolean deleted = redisTemplate.delete(cacheKey);
                    if (Boolean.TRUE.equals(deleted)) {
                        deletedCount++;
                    }
                } catch (Exception e) {
                    log.warn("删除缓存键失败：{}，错误：{}", cacheKey, e.getMessage());
                }
            }
            
            log.info("清除用户权限缓存成功，用户ID：{}，删除缓存键数量：{}/{}", userId, deletedCount, cacheKeys.length);
            
        } catch (Exception e) {
            log.error("清除用户权限缓存失败，用户ID：{}", userId, e);
            // 不抛出异常，避免影响主流程
        }
    }
    
    @Override
    public void refreshUserPermissionCache(Long userId) throws Exception {
        if (userId == null) {
            userId = SecurityUtils.getCurrentUserId();
        }
        
        if (userId == null) {
            log.warn("用户ID为空，无法刷新权限缓存");
            return;
        }
        
        try {
            log.info("开始刷新用户权限缓存，用户ID：{}", userId);
            
            // 1. 清除现有缓存
            clearUserPermissionCache(userId);
            
            // 2. 重新构建并缓存
            DataScopeInfo dataScopeInfo = buildUserDataScope(userId);
            String cacheKey = CACHE_KEY_PREFIX + userId;
            setCachedDataScope(cacheKey, dataScopeInfo);
            
            log.info("用户权限缓存刷新成功，用户ID：{}", userId);
            
        } catch (Exception e) {
            log.error("刷新用户权限缓存失败，用户ID：{}", userId, e);
            throw new DataScopeException("刷新用户权限缓存失败：" + e.getMessage());
        }
    }
    
    @Override
    public void clearAllPermissionCache() throws Exception {
        try {
            log.info("开始清除所有权限缓存");
            
            // 定义所有缓存键模式
            String[] cachePatterns = {
                CACHE_KEY_PREFIX + "*",
                CACHE_PREFIX_NORMAL_USER_DATA_SCOPE + "*",
                CACHE_PREFIX_NORMAL_USER_PROPERTY_COMPANY_IDS + "*",
                CACHE_PREFIX_NORMAL_USER_COMMUNITY_IDS + "*",
                CACHE_PREFIX_NORMAL_USER_SUPER_SUPER_ADMIN + "*",
                CACHE_PREFIX_OWNER_HOUSEHOLD_IDS + "*"
            };
            
            int totalDeleted = 0;
            
            // 批量清除各种类型的缓存
            for (String pattern : cachePatterns) {
                try {
                    Set<String> keys = redisTemplate.keys(pattern);
                    if (keys != null && !keys.isEmpty()) {
                        Long deletedCount = redisTemplate.delete(keys);
                        if (deletedCount != null) {
                            totalDeleted += deletedCount.intValue();
                            log.debug("清除缓存模式：{}，删除数量：{}", pattern, deletedCount);
                        }
                    }
                } catch (Exception e) {
                    log.warn("清除缓存模式失败：{}，错误：{}", pattern, e.getMessage());
                }
            }
            
            log.info("清除所有权限缓存成功，总删除数量：{}", totalDeleted);
            
        } catch (Exception e) {
            log.error("清除所有权限缓存失败", e);
            throw new DataScopeException("清除所有权限缓存失败：" + e.getMessage());
        }
    }
    
    /**
     * 批量清除用户权限缓存（生产环境优化版本）
     * 
     * @param userIds 用户ID列表
     */
    public void batchClearUserPermissionCache(List<Long> userIds) {
        if (userIds == null || userIds.isEmpty()) {
            log.warn("用户ID列表为空，跳过批量清除缓存");
            return;
        }
        
        log.info("开始批量清除用户权限缓存，用户数量：{}", userIds.size());
        
        int successCount = 0;
        int failCount = 0;
        
        for (Long userId : userIds) {
            try {
                clearUserPermissionCache(userId);
                successCount++;
            } catch (Exception e) {
                log.warn("清除用户权限缓存失败，用户ID：{}，错误：{}", userId, e.getMessage());
                failCount++;
            }
        }
        
        log.info("批量清除用户权限缓存完成，成功：{}，失败：{}", successCount, failCount);
    }
    
    /**
     * 获取缓存统计信息（生产环境监控用）
     * 
     * @return 缓存统计信息
     */
    public Map<String, Object> getCacheStatistics() {
        Map<String, Object> statistics = new java.util.HashMap<>();
        
        try {
            // 统计各种缓存的数量
            String[] cachePatterns = {
                CACHE_KEY_PREFIX + "*",
                CACHE_PREFIX_NORMAL_USER_DATA_SCOPE + "*",
                CACHE_PREFIX_NORMAL_USER_PROPERTY_COMPANY_IDS + "*",
                CACHE_PREFIX_NORMAL_USER_COMMUNITY_IDS + "*",
                CACHE_PREFIX_NORMAL_USER_SUPER_SUPER_ADMIN + "*",
                CACHE_PREFIX_OWNER_HOUSEHOLD_IDS + "*"
            };
            
            String[] cacheNames = {
                "data_scope_cache",
                "user_data_scope_cache", 
                "property_company_ids_cache",
                "community_ids_cache",
                "super_admin_cache",
                "household_ids_cache"
            };
            
            for (int i = 0; i < cachePatterns.length; i++) {
                try {
                    Set<String> keys = redisTemplate.keys(cachePatterns[i]);
                    int count = keys != null ? keys.size() : 0;
                    statistics.put(cacheNames[i], count);
                } catch (Exception e) {
                    log.warn("获取缓存统计失败：{}，错误：{}", cacheNames[i], e.getMessage());
                    statistics.put(cacheNames[i], -1);
                }
            }
            
            statistics.put("total_cache_count", statistics.values().stream()
                .filter(v -> v instanceof Integer && (Integer) v >= 0)
                .mapToInt(v -> (Integer) v)
                .sum());
            
        } catch (Exception e) {
            log.error("获取缓存统计信息失败", e);
        }
        
        return statistics;
    }
    
    @Override
    public void hasCommunityPermission(Long communityId) throws Exception {
        Long userId = SecurityUtils.getCurrentUserId();
        if (!hasCommunityPermission(userId, communityId)) {
            throw new DataScopeException("用户无权限访问社区ID：" + communityId);
        }
    }
    
    @Override
    public List<Long> getAuthorizedCommunityIds(Long userId, List<Long> communityIds) throws Exception {
        if (communityIds == null || communityIds.isEmpty()) {
            return Collections.emptyList();
        }
        
        DataScopeInfo dataScopeInfo = getUserDataScope(userId);
        if (dataScopeInfo.isSuperAdmin()) {
            return new ArrayList<>(communityIds);
        }
        
        return communityIds.stream()
                .filter(dataScopeInfo::hasCommunityPermission)
                .collect(Collectors.toList());
    }
    
    @Override
    public List<Long> getUserCommunityIds(Long userId) throws Exception {
        DataScopeInfo dataScopeInfo = getUserDataScope(userId);
        return dataScopeInfo.getCommunityIds();
    }
    
    @Override
    public boolean isPropertyCompanyUser(Long userId) throws Exception {
        DataScopeInfo dataScopeInfo = getUserDataScope(userId);
        return dataScopeInfo.isPropertyCompanyUser();
    }
    
    @Override
    @Cacheable(value = "dataScope:propertyCompanyIds", key = "#userId", unless = "#result == null || #result.isEmpty()")
    public List<Long> getUserPropertyCompanyIds(Long userId) throws Exception {
        if (userId == null) {
            log.error("用户ID为空，无法获取用户物业公司列表");
            return Collections.emptyList();
        }
        
        // 直接从数据库查询，由Spring Cache自动管理缓存
        log.debug("查询用户物业公司列表，用户ID：{}", userId);
        LambdaQueryWrapper<UserPropertyCompany> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserPropertyCompany::getUserId, userId);
        wrapper.eq(UserPropertyCompany::getStatus, 1); // 只查询启用状态的关联
        wrapper.select(UserPropertyCompany::getPropertyCompanyId);
        List<UserPropertyCompany> userPropertyCompanies = userPropertyCompanyMapper.selectList(wrapper);
        
        List<Long> propertyCompanyIds = userPropertyCompanies.stream()
                .map(UserPropertyCompany::getPropertyCompanyId)
                .distinct()
                .collect(Collectors.toList());
        
        log.debug("用户物业公司列表查询完成，用户ID：{}，物业公司数量：{}", userId, propertyCompanyIds.size());
        return propertyCompanyIds;
    }
    
    // =============== 新增业主权限相关方法实现 ===============
    
    @Override
    public boolean isOwnerUser(Long userId) throws Exception {
        if (userId == null) {
            return false;
        }
        
        try {
        	// 业主判断逻辑：根据user_id查询sc_owner表
        	log.info(" ♂♂♂ 开始查询业主信息，用户ID：{}", userId);
        	OwnerInfoDTO owner = ownerFeignService.getOwnerByUserId(userId);
        	log.info(" ♂♂♂ 业主查询结果，用户ID：{}，owner对象：{}，owner.id：{}", userId, owner, owner != null ? owner.getId() : "null");
        	
        	if (owner != null && owner.getId() != null) {
        		log.info(" ♂♂♂ 用户是业主，用户ID：{}，业主ID：{}", userId, owner.getId());
        		return true;
        	}
        	
            // 检查用户角色
            List<String> userRoles = getUserRolesFromUserService(userId);
            if (userRoles != null && userRoles.contains(RoleCodeEnum.OWNER.getCode())) {
                log.info(" ♂♂♂ 用户分配了业主角色，用户ID：{}", userId);
                return true;
            }
            
            log.warn(" ♂♂♂ 用户不是业主，用户ID：{}，owner对象：{}", userId, owner);
            return false;
        } catch (Exception e) {
            log.warn(" ♂♂♂ 检查业主权限失败，用户ID：{}，错误：{}", userId, e.getMessage());
            return false;
        }
    }
    
    @Override
    @Cacheable(value = "dataScope:ownerHouseholdIds", key = "#userId", unless = "#result == null || #result.isEmpty()")
    public List<Long> getOwnerHouseholdIds(Long userId) throws Exception {
        if (userId == null) {
            log.error("用户ID为空，无法获取业主房户列表");
            return Collections.emptyList();
        }
        
        // 执行业主房户查询逻辑，由Spring Cache自动管理缓存
        log.debug("执行业主房户查询逻辑，用户ID：{}", userId);
        List<Long> householdIds = getOwnerHouseholdIdsByNewLogic(userId);
        
        if (householdIds == null) {
            householdIds = new ArrayList<>();
        }
        
        log.debug("业主房户列表查询完成，用户ID：{}，房户数量：{}", userId, householdIds.size());
        return householdIds;
    }
    
    /**
     * 新的用户房户查询逻辑（仅业主身份）
     * 根据user_id查询sc_owner表，查询用户是否业主，如果是业主，获取业主关联的房户ID
     * 
     * @param userId 用户ID
     * @return 业主关联的房户ID列表
     */
    private List<Long> getOwnerHouseholdIdsByNewLogic(Long userId) throws Exception {
        log.info("执行新的用户房户查询逻辑（仅业主身份），用户ID：{}", userId);
        
        // 根据user_id查询sc_owner表，查询用户是否业主
        try {
            OwnerInfoDTO owner = ownerFeignService.getOwnerByUserId(userId);
            if (owner != null && owner.getId() != null) {
                log.info("用户是业主，用户ID：{}，业主ID：{}", userId, owner.getId());
                
                // 如果是业主，则根据sc_owner表中查出来的数据，再到sc_owner_household中查询，获取到业主关联的所有房户信息
                List<Long> ownerHouseholdIds = ownerFeignService.getOwnerHouseholdIdsByOwnerId(owner.getId());
                if (ownerHouseholdIds != null && !ownerHouseholdIds.isEmpty()) {
                    log.info("获取业主关联房户列表，用户ID：{}，业主ID：{}，业主房户数量：{}", userId, owner.getId(), ownerHouseholdIds.size());
                    return ownerHouseholdIds;
                } else {
                    log.info("业主没有关联的房户，用户ID：{}，业主ID：{}", userId, owner.getId());
                    return Collections.emptyList();
                }
            } else {
                log.info("用户不是业主，用户ID：{}", userId);
                return Collections.emptyList();
            }
        } catch (Exception e) {
            log.warn("查询用户业主信息失败，用户ID：{}，错误：{}", userId, e.getMessage());
            return Collections.emptyList();
        }
    }
    
    
    /**
     * 从缓存获取业主房户ID列表（生产环境优化版本）
     * 
     * @param cacheKey 缓存键
     * @return 房户ID列表，如果缓存不存在或异常则返回null
     */
    private List<Long> getCachedHouseholdIds(String cacheKey) {
        for (int i = 0; i < CACHE_RETRY_TIMES; i++) {
            try {
                Object cacheResult = redisTemplate.opsForValue().get(cacheKey);
                
                if (cacheResult == null) {
                    return null;
                }
                
                if (cacheResult instanceof List) {
                    return convertToLongList((List<?>) cacheResult);
                }
                
                // 缓存数据格式错误，清除缓存
                log.warn("业主房户缓存数据格式错误，清除缓存，缓存键：{}", cacheKey);
                redisTemplate.delete(cacheKey);
                return null;
                
            } catch (Exception e) {
                log.warn("业主房户缓存获取失败，重试次数：{}/{}，缓存键：{}，错误：{}", 
                    i + 1, CACHE_RETRY_TIMES, cacheKey, e.getMessage());
                
                if (i == CACHE_RETRY_TIMES - 1) {
                    log.error("业主房户缓存获取最终失败，缓存键：{}", cacheKey, e);
                }
            }
        }
        return null;
    }
    
    /**
     * 设置缓存业主房户ID列表（生产环境优化版本）
     * 
     * @param cacheKey 缓存键
     * @param householdIds 房户ID列表
     */
    private void setCachedHouseholdIds(String cacheKey, List<Long> householdIds) {
        if (householdIds == null) {
            log.warn("业主房户ID列表为空，不进行缓存，缓存键：{}", cacheKey);
            return;
        }
        
        for (int i = 0; i < CACHE_RETRY_TIMES; i++) {
            try {
                redisTemplate.opsForValue().set(cacheKey, householdIds, HOUSEHOLD_IDS_CACHE_EXPIRE, TimeUnit.MINUTES);
                log.debug("业主房户ID列表缓存成功，缓存键：{}，房户数量：{}，过期时间：{}分钟", 
                    cacheKey, householdIds.size(), HOUSEHOLD_IDS_CACHE_EXPIRE);
                return;
                
            } catch (Exception e) {
                log.warn("业主房户缓存设置失败，重试次数：{}/{}，缓存键：{}，错误：{}", 
                    i + 1, CACHE_RETRY_TIMES, cacheKey, e.getMessage());
                
                if (i == CACHE_RETRY_TIMES - 1) {
                    log.error("业主房户缓存设置最终失败，缓存键：{}", cacheKey, e);
                }
            }
        }
    }
    
    @Override
    public List<Long> getOwnerHouseholdIdsByPropertyCompanies(Long userId, List<Long> propertyCompanyIds) throws Exception {
        if (userId == null || propertyCompanyIds == null || propertyCompanyIds.isEmpty()) {
            return Collections.emptyList();
        }
        
        try {
            // 调用业主Feign接口获取指定物业公司范围内的房户ID列表
            List<Long> householdIds = ownerFeignService.getOwnerHouseholdIdsByPropertyCompanies(userId, propertyCompanyIds);
            log.info(" ♂♂♂ 获取业主在物业公司范围内的房户ID列表，用户ID：{}，物业公司数量：{}，房户数量：{}", 
                    userId, propertyCompanyIds.size(), householdIds.size());
            return householdIds;
        } catch (Exception e) {
            log.warn(" ♂♂♂ 获取业主在物业公司范围内的房户ID列表失败，用户ID：{}，错误：{}", userId, e.getMessage());
            return Collections.emptyList();
        }
    }
    
    @Override
    public boolean hasHouseholdPermission(Long userId, Long householdId) throws Exception {
        if (userId == null || householdId == null) {
            return false;
        }
        
        // 超级管理员拥有所有权限
        if (isUserSuperAdmin(userId)) {
            return true;
        }
        
        // 获取业主房户ID列表
        List<Long> householdIds = getOwnerHouseholdIds(userId);
        return householdIds.contains(householdId);
    }
    
    @Override
    public void validateBatchHouseholdPermission(Long userId, List<Long> householdIds) throws Exception {
        if (userId == null || householdIds == null || householdIds.isEmpty()) {
            return;
        }
        
        // 超级管理员拥有所有权限
        if (isUserSuperAdmin(userId)) {
            return;
        }
        
        // 获取业主房户ID列表
        List<Long> userHouseholdIds = getOwnerHouseholdIds(userId);
        
        // 检查是否有权限访问所有房户
        for (Long householdId : householdIds) {
            if (!userHouseholdIds.contains(householdId)) {
                throw new DataScopeException("用户无权限访问房户ID：" + householdId);
            }
        }
    }
    
    @Override
    public List<Long> getAuthorizedHouseholdIds(Long userId, List<Long> householdIds) throws Exception {
        if (userId == null || householdIds == null || householdIds.isEmpty()) {
            return Collections.emptyList();
        }
        
        // 超级管理员拥有所有权限
        if (isUserSuperAdmin(userId)) {
            return householdIds;
        }
        
        // 获取业主房户ID列表
        List<Long> userHouseholdIds = getOwnerHouseholdIds(userId);
        
        // 返回有权限的房户ID列表
        return householdIds.stream()
                .filter(userHouseholdIds::contains)
                .collect(Collectors.toList());
    }
    
    // =============== 私有方法 ===============
    /**
     * 构建用户数据权限范围核心对象
     * @author Wu.Liang
     * @date 2025年8月8日
     * @param userId 用户ID
     * @return
     * @throws Exception
     */
    private DataScopeInfo buildUserDataScope(Long userId) throws Exception {
        long startTime = System.currentTimeMillis();
        log.info("开始构建用户数据权限范围，用户ID：{}", userId);
        
        try {
            // 1. 检查是否为超级管理员
            boolean isSuperAdmin = isUserSuperAdmin(userId);
            log.info("用户{}超级管理员检查结果：{}", userId, isSuperAdmin);
            
            // 2. 检查是否为业主（基于业主表关联关系）
            boolean isOwner = isOwnerUser(userId);
            List<Long> householdIds = isOwner ? getOwnerHouseholdIds(userId) : new ArrayList<>();
            log.info("用户{}业主检查结果：isOwner={}, householdIds数量={}", userId, isOwner, householdIds.size());
            
            // 3. 检查是否为物业公司人员（基于物业公司关联关系）
            List<Long> propertyCompanyIds = getUserPropertyCompanyIds(userId);
            boolean isPropertyCompanyUser = (propertyCompanyIds != null && !propertyCompanyIds.isEmpty());
            log.info("用户{}物业管理员检查结果：isPropertyCompanyUser={}, propertyCompanyIds={}", userId, isPropertyCompanyUser, propertyCompanyIds);
            
            // 4. 获取社区ID集合
            List<Long> communityIds = new ArrayList<>();
            if (isSuperAdmin) {
                // 超级管理员看到全部社区
                communityIds = regionAddressFeignService.getAllCommunities().stream()
                    .map(CommunityInfoDTO::getId).distinct().collect(Collectors.toList());
                log.info("用户{}超级管理员获取社区ID，社区数量={}", userId, communityIds.size());
            } else if (isPropertyCompanyUser) {
                // 物业人员看到关联的社区
                log.info("用户{}物业管理员开始获取社区ID，物业公司IDs={}", userId, propertyCompanyIds);
                communityIds = getUserCommunityIds(userId, propertyCompanyIds);
                log.info("用户{}物业管理员获取社区ID完成，社区数量={}, 社区IDs={}", userId, communityIds.size(), communityIds);
            } else {
                log.warn("用户{}既不是超级管理员也不是物业公司用户，无数据权限", userId);
            }
        
            // 5. 确定描述信息（基于身份判断，不再使用dataScopeType）
            String scopeDescription;
            if (isSuperAdmin) {
                scopeDescription = "超级管理员拥有所有数据权限";
            } else if (isPropertyCompanyUser) {
                scopeDescription = "物业公司用户，可访问关联的物业公司和社区数据";
            } else if (isOwner) {
                scopeDescription = "业主用户，可访问关联的房户数据";
            } else {
                scopeDescription = "普通用户，无数据权限";
            }
            
            // 6. 构建DataScopeInfo对象（支持多重身份，不再使用dataScopeType）
            log.info("开始构建DataScopeInfo对象，用户ID={}, householdIds={}, propertyCompanyIds={}", 
                userId, householdIds, propertyCompanyIds);
            
            DataScopeInfo dataScopeInfo = new DataScopeInfo(
                userId,
                communityIds,
                propertyCompanyIds,
                householdIds,
                scopeDescription
            );
            
            // 7. 验证构造函数是否正确设置了身份字段
            log.info("构造函数后的身份字段：用户ID={}, isSuperAdmin={}, isPropertyCompanyUser={}, isOwnerUser={}", 
                userId, dataScopeInfo.isSuperAdmin(), dataScopeInfo.isPropertyCompanyUser(), dataScopeInfo.isOwnerUser());
        
        // 8. 设置多重身份标识（基于实际关联关系，不是数据权限类型）
        dataScopeInfo.setSuperAdmin(isSuperAdmin);
        dataScopeInfo.setPropertyCompanyUser(isPropertyCompanyUser);
        dataScopeInfo.setOwnerUser(isOwner);
        
        // 9. 检查用户角色权限（新增8个角色权限判断）
        if (isPropertyCompanyUser) {
            List<String> userRoles = getUserRolesFromUserService(userId);
            if (userRoles != null && !userRoles.isEmpty()) {
                // 保洁人员角色判断
                dataScopeInfo.setCleaningStaff(userRoles.contains(RoleCodeEnum.CLEANING_STAFF.getCode()));
                // 保洁管理角色判断
                dataScopeInfo.setCleaningAdmin(userRoles.contains(RoleCodeEnum.CLEANING_ADMIN.getCode()));
                // 安保人员角色判断
                dataScopeInfo.setSecurityStaff(userRoles.contains(RoleCodeEnum.SECURITY_STAFF.getCode()));
                // 安保管理角色判断
                dataScopeInfo.setSecurityAdmin(userRoles.contains(RoleCodeEnum.SECURITY_ADMIN.getCode()));
                // 停车人员角色判断
                dataScopeInfo.setParkingStaff(userRoles.contains(RoleCodeEnum.PARKING_STAFF.getCode()));
                // 停车管理角色判断
                dataScopeInfo.setParkingAdmin(userRoles.contains(RoleCodeEnum.PARKING_ADMIN.getCode()));
                // 物业人员角色判断
                dataScopeInfo.setPropertyStaff(userRoles.contains(RoleCodeEnum.PROPERTY_STAFF.getCode()));
                // 物业管理角色判断
                dataScopeInfo.setPropertyAdmin(userRoles.contains(RoleCodeEnum.PROPERTY_ADMIN.getCode()));
                
                log.info(" ♂♂♂ 用户ID={}角色权限判断结果：保洁人员={}, 保洁管理={}, 安保人员={}, 安保管理={}, 停车人员={}, 停车管理={}, 物业人员={}, 物业管理={}", 
                    userId, 
                    dataScopeInfo.isCleaningStaff(), 
                    dataScopeInfo.isCleaningAdmin(),
                    dataScopeInfo.isSecurityStaff(), 
                    dataScopeInfo.isSecurityAdmin(),
                    dataScopeInfo.isParkingStaff(), 
                    dataScopeInfo.isParkingAdmin(),
                    dataScopeInfo.isPropertyStaff(), 
                    dataScopeInfo.isPropertyAdmin());
            }
        }
        
            // 8. 设置多重身份标识（基于实际关联关系，不是数据权限类型）
            dataScopeInfo.setSuperAdmin(isSuperAdmin);
            dataScopeInfo.setPropertyCompanyUser(isPropertyCompanyUser);
            dataScopeInfo.setOwnerUser(isOwner);
            
            // 9. 检查用户角色权限（新增8个角色权限判断）
            if (isPropertyCompanyUser) {
                List<String> userRoles = getUserRolesFromUserService(userId);
                if (userRoles != null && !userRoles.isEmpty()) {
                    // 保洁人员角色判断
                    dataScopeInfo.setCleaningStaff(userRoles.contains(RoleCodeEnum.CLEANING_STAFF.getCode()));
                    // 保洁管理角色判断
                    dataScopeInfo.setCleaningAdmin(userRoles.contains(RoleCodeEnum.CLEANING_ADMIN.getCode()));
                    // 安保人员角色判断
                    dataScopeInfo.setSecurityStaff(userRoles.contains(RoleCodeEnum.SECURITY_STAFF.getCode()));
                    // 安保管理角色判断
                    dataScopeInfo.setSecurityAdmin(userRoles.contains(RoleCodeEnum.SECURITY_ADMIN.getCode()));
                    // 停车人员角色判断
                    dataScopeInfo.setParkingStaff(userRoles.contains(RoleCodeEnum.PARKING_STAFF.getCode()));
                    // 停车管理角色判断
                    dataScopeInfo.setParkingAdmin(userRoles.contains(RoleCodeEnum.PARKING_ADMIN.getCode()));
                    // 物业人员角色判断
                    dataScopeInfo.setPropertyStaff(userRoles.contains(RoleCodeEnum.PROPERTY_STAFF.getCode()));
                    // 物业管理角色判断
                    dataScopeInfo.setPropertyAdmin(userRoles.contains(RoleCodeEnum.PROPERTY_ADMIN.getCode()));
                    
                    log.info("用户{}角色权限设置完成：保洁人员={}, 保洁管理={}, 安保人员={}, 安保管理={}, 停车人员={}, 停车管理={}, 物业人员={}, 物业管理={}", 
                        userId,
                        dataScopeInfo.isCleaningStaff(), 
                        dataScopeInfo.isCleaningAdmin(),
                        dataScopeInfo.isSecurityStaff(), 
                        dataScopeInfo.isSecurityAdmin(),
                        dataScopeInfo.isParkingStaff(), 
                        dataScopeInfo.isParkingAdmin(),
                        dataScopeInfo.isPropertyStaff(), 
                        dataScopeInfo.isPropertyAdmin());
                }
            }
            
            // 10. 验证最终的身份字段
            log.info("最终身份字段：用户ID={}, isSuperAdmin={}, isPropertyCompanyUser={}, isOwnerUser={}", 
                userId, dataScopeInfo.isSuperAdmin(), dataScopeInfo.isPropertyCompanyUser(), dataScopeInfo.isOwnerUser());
            
            long endTime = System.currentTimeMillis();
            log.info("用户数据权限信息构建完成，用户ID：{}，耗时：{}ms，超级管理员={}, 物业管理员={}, 业主={}, 社区数量={}", 
                userId, endTime - startTime, isSuperAdmin, isPropertyCompanyUser, isOwner, communityIds.size());
            
            return dataScopeInfo;
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("构建用户数据权限范围失败，用户ID：{}，耗时：{}ms，错误：{}", userId, endTime - startTime, e.getMessage(), e);
            throw e;
        }
    }
    
    /**
     * 查询用户所在物业公司管理的所有社区ID集合
     * @author Wu.Liang
     * @date 2025年8月9日
     * @param userId 用户ID
     * @param propertyCompanyIds 用户关联的所有物业公司ID
     * @return
     */
    private List<Long> getUserCommunityIds(Long userId, List<Long> propertyCompanyIds) {
        log.info("开始获取用户社区ID，用户ID={}, 物业公司IDs={}", userId, propertyCompanyIds);
        
        if (propertyCompanyIds == null || propertyCompanyIds.isEmpty()) {
            log.warn("物业公司ID列表为空，用户ID={}", userId);
            return Collections.emptyList();
        }
        
        try {
            log.info("从数据库查询用户社区ID，用户ID={}, 物业公司IDs={}", userId, propertyCompanyIds);
            
            // 从数据库查询物业公司关联的社区
            LambdaQueryWrapper<PropertyCompanyCommunity> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(PropertyCompanyCommunity::getPropertyCompanyId, propertyCompanyIds);
            // 修复：status字段为NULL时也应该查询出来，因为NULL表示正常状态
            wrapper.and(w -> w.eq(PropertyCompanyCommunity::getStatus, 1).or().isNull(PropertyCompanyCommunity::getStatus));
            wrapper.select(PropertyCompanyCommunity::getCommunityId);
            List<PropertyCompanyCommunity> propertyCompanyCommunities = propertyCompanyCommunityMapper.selectList(wrapper);
            
            log.info("数据库查询结果，用户ID={}, 查询到的关联记录数={}", userId, propertyCompanyCommunities.size());
            
            if (propertyCompanyCommunities.isEmpty()) {
                log.warn("物业公司未关联任何社区，用户ID={}, 物业公司IDs={}", userId, propertyCompanyIds);
                return Collections.emptyList();
            }
            
            List<Long> communityIds = propertyCompanyCommunities.stream()
                    .map(PropertyCompanyCommunity::getCommunityId)
                    .distinct()
                    .collect(Collectors.toList());
            
            log.info("最终社区ID列表，用户ID={}, 社区IDs={}", userId, communityIds);
            
            return communityIds;
            
        } catch (Exception e) {
            log.error("获取用户社区ID失败，用户ID={}, 物业公司IDs={}, 错误：{}", userId, propertyCompanyIds, e.getMessage(), e);
            return Collections.emptyList();
        }
    }
    
    private String getCurrentUserIp() {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes != null) {
                HttpServletRequest request = attributes.getRequest();
                String ip = request.getHeader("X-Forwarded-For");
                if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
                    ip = request.getHeader("Proxy-Client-IP");
                }
                if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
                    ip = request.getHeader("WL-Proxy-Client-IP");
                }
                if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
                    ip = request.getHeader("HTTP_CLIENT_IP");
                }
                if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
                    ip = request.getHeader("HTTP_X_FORWARDED_FOR");
                }
                if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
                    ip = request.getRemoteAddr();
                }
                return ip;
            }
        } catch (Exception e) {
            log.warn("获取用户IP失败", e);
        }
        return "unknown";
    }
    
    private String getCurrentUserAgent() {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes != null) {
                HttpServletRequest request = attributes.getRequest();
                return request.getHeader("User-Agent");
            }
        } catch (Exception e) {
            log.warn("获取User-Agent失败", e);
        }
        return "unknown";
    }
    
    private DataScopeInfo convertMapToDataScopeInfo(Map<String, Object> map) throws Exception {
        try {
            DataScopeInfo dataScopeInfo = new DataScopeInfo();
            dataScopeInfo.setUserId(convertToLong(map.get("userId")));
            dataScopeInfo.setCommunityIds(convertToLongList(map.get("communityIds")));
            dataScopeInfo.setPropertyCompanyIds(convertToLongList(map.get("propertyCompanyIds")));
            dataScopeInfo.setHouseholdIds(convertToLongList(map.get("householdIds")));
            dataScopeInfo.setScopeDescription((String) map.get("scopeDescription"));
            
            // 确保所有身份字段都被正确设置
            Boolean isSuperAdmin = (Boolean) map.get("isSuperAdmin");
            Boolean isPropertyCompanyUser = (Boolean) map.get("propertyCompanyUser");
            Boolean isOwnerUser = (Boolean) map.get("ownerUser");
            
            // 如果从map中获取不到，则基于关联关系重新计算
            if (isSuperAdmin == null) {
                isSuperAdmin = false;
            }
            if (isPropertyCompanyUser == null) {
                List<Long> propertyCompanyIds = convertToLongList(map.get("propertyCompanyIds"));
                isPropertyCompanyUser = (Boolean) (propertyCompanyIds != null && !propertyCompanyIds.isEmpty());
            }
            if (isOwnerUser == null) {
                List<Long> householdIds = convertToLongList(map.get("householdIds"));
                isOwnerUser = (Boolean) (householdIds != null && !householdIds.isEmpty());
            }
            
            dataScopeInfo.setSuperAdmin(isSuperAdmin);
            dataScopeInfo.setPropertyCompanyUser(isPropertyCompanyUser);
            dataScopeInfo.setOwnerUser(isOwnerUser);
            
            return dataScopeInfo;
        } catch (Exception e) {
            throw new Exception("转换DataScopeInfo失败" + e.getMessage());
        }
    }
    
    private Long convertToLong(Object obj) {
        if (obj == null) {
            return null;
        }
        if (obj instanceof Long) {
            return (Long) obj;
        }
        if (obj instanceof Integer) {
            return ((Integer) obj).longValue();
        }
        if (obj instanceof String) {
            try {
                return Long.parseLong((String) obj);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }
    
    private Integer convertToInteger(Object obj) {
        if (obj == null) {
            return null;
        }
        if (obj instanceof Integer) {
            return (Integer) obj;
        }
        if (obj instanceof Long) {
            return ((Long) obj).intValue();
        }
        if (obj instanceof String) {
            try {
                return Integer.parseInt((String) obj);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }
    
    private List<Long> convertToLongList(Object obj) {
        if (obj == null) {
            return Collections.emptyList();
        }
        if (obj instanceof List) {
            List<?> list = (List<?>) obj;
            return list.stream()
                    .map(this::convertToLong)
                    .filter(item -> item != null)
                    .collect(Collectors.toList());
        } else if (obj instanceof Map) {
            // 处理LinkedHashMap等Map类型，可能是JSON反序列化结果
            Map<?, ?> map = (Map<?, ?>) obj;
            return map.values().stream()
                    .map(this::convertToLong)
                    .filter(item -> item != null)
                    .collect(Collectors.toList());
        }
        return Collections.emptyList();
    }
    
    /**
     * 从用户服务获取用户角色列表
     * @param userId 用户ID
     * @return 用户角色代码列表
     */
    private List<String> getUserRolesFromUserService(Long userId) {
    	if (StrUtil.isBlankIfStr(userId)) {
    		return Collections.emptyList();
    	}
        try {
        	List<RoleDTO> userRoles = userFeignService.getUserRoles(userId);
            if (userRoles == null || userRoles.isEmpty()) {
                log.debug(" ♂♂♂ 用户{}没有分配任何角色", userId);
                return Collections.emptyList();
            }
            List<String> roleCodes = userRoles.stream()
                .map(RoleDTO::getRoleCode)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
            log.debug(" ♂♂♂ 用户{}的角色代码列表：{}", userId, roleCodes);
            return roleCodes;
        } catch (Exception e) {
            log.warn(" ♂♂♂ 获取用户角色失败，用户ID：{}，错误：{}", userId, e.getMessage());
            return Collections.emptyList();
        }
    }
    
    // =============== 添加缺失的方法实现 ===============
    
    @Override
    public String getCurrentUserDataScopeString() throws Exception {
        Long userId = SecurityUtils.getCurrentUserId();
        return getUserDataScopeString(userId);
    }
    
    @Override
    @Cacheable(value = "dataScope:userScopeString", key = "#userId", unless = "#result == null")
    public String getUserDataScopeString(Long userId) throws Exception {
        if (userId == null) {
            return DataScope.SELF.getCode();
        }

        // 检查用户角色
        String dataScope;
        if (isUserSuperAdmin(userId)) {
            dataScope = DataScope.ALL.getCode();
        } else if (isOwnerUser(userId)) {
            dataScope = DataScope.CUSTOM.getCode();
        } else {
            List<Long> propertyCompanyIds = getUserPropertyCompanyIds(userId);
            if (propertyCompanyIds != null && !propertyCompanyIds.isEmpty()) {
                dataScope = DataScope.PROPERTY_COMPANY_AND_COMMUNITY.getCode();
            } else {
                dataScope = DataScope.SELF.getCode();
            }
        }

        log.debug("获取用户数据权限范围，用户ID：{}，权限范围：{}", userId, dataScope);
        return dataScope;
    }
    
    @Override
    public boolean isCurrentUserSuperAdmin() throws Exception {
        Long userId = SecurityUtils.getCurrentUserId();
        return isUserSuperAdmin(userId);
    }
    

    
    @Override
    @Cacheable(value = "dataScope:isSuperAdmin", key = "#userId", unless = "#result == null")
    public boolean isUserSuperAdmin(Long userId) throws Exception {
        if (userId == null) {
            return false;
        }
        
        try {
            boolean isSuperAdmin = false;
            
            // 检查用户类型
            UserDTO userDTO = userFeignService.getUserById(userId);
            if (userDTO != null && userDTO.getUserType() != null) {
                if ("SUPER_ADMIN".equals(userDTO.getUserType())) {
                    log.info(" ♂♂♂ 用户类型是超级管理员，用户ID：{}", userId);
                    isSuperAdmin = true;
                }
            }
            
            // 检查用户角色
            if (!isSuperAdmin) {
                List<String> userRoles = getUserRolesFromUserService(userId);
                if (userRoles != null && userRoles.contains(RoleCodeEnum.SUPER_ADMIN.getCode())) {
                    log.info(" ♂♂♂ 用户分配了超级管理员角色，用户ID：{}", userId);
                    isSuperAdmin = true;
                }
            }
            
            log.info(" ♂♂♂ isSuperAdmin={}，用户ID：{}", isSuperAdmin, userId);
            return isSuperAdmin;
        } catch (Exception e) {
            log.warn(" ♂♂♂ 获取用户信息失败，用户ID：{}，错误：{}", userId, e.getMessage());
            return false;
        }
    }
    
    // =============== 新增缺失的方法实现 ===============
    
    @Override
    public List<Long> getCurrentUserCommunityIds() throws Exception {
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw DataScopeException.userInfoError();
        }
        return getUserCommunityIds(userId);
    }
    
    @Override
    public boolean isCurrentUserPropertyCompanyUser() throws Exception {
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw DataScopeException.userInfoError();
        }
        return isPropertyCompanyUser(userId);
    }
    

    
    /**
     * 从缓存获取用户物业公司ID列表（生产环境优化版本）
     * 
     * @param cacheKey 缓存键
     * @return 物业公司ID列表，如果缓存不存在或异常则返回null
     */
    private List<Long> getCachedPropertyCompanyIds(String cacheKey) {
        for (int i = 0; i < CACHE_RETRY_TIMES; i++) {
            try {
                Object cacheResult = redisTemplate.opsForValue().get(cacheKey);
                
                if (cacheResult == null) {
                    return null;
                }
                
                if (cacheResult instanceof List) {
                    return convertToLongList((List<?>) cacheResult);
                }
                
                // 缓存数据格式错误，清除缓存
                log.warn("物业公司缓存数据格式错误，清除缓存，缓存键：{}", cacheKey);
                redisTemplate.delete(cacheKey);
                return null;
                
            } catch (Exception e) {
                log.warn("物业公司缓存获取失败，重试次数：{}/{}，缓存键：{}，错误：{}", 
                    i + 1, CACHE_RETRY_TIMES, cacheKey, e.getMessage());
                
                if (i == CACHE_RETRY_TIMES - 1) {
                    log.error("物业公司缓存获取最终失败，缓存键：{}", cacheKey, e);
                }
            }
        }
        return null;
    }
    
    /**
     * 设置缓存用户物业公司ID列表（生产环境优化版本）
     * 
     * @param cacheKey 缓存键
     * @param propertyCompanyIds 物业公司ID列表
     */
    private void setCachedPropertyCompanyIds(String cacheKey, List<Long> propertyCompanyIds) {
        if (propertyCompanyIds == null) {
            log.warn("物业公司ID列表为空，不进行缓存，缓存键：{}", cacheKey);
            return;
        }
        
        for (int i = 0; i < CACHE_RETRY_TIMES; i++) {
            try {
                redisTemplate.opsForValue().set(cacheKey, propertyCompanyIds, USER_ROLES_CACHE_EXPIRE, TimeUnit.MINUTES);
                log.debug("物业公司ID列表缓存成功，缓存键：{}，物业公司数量：{}，过期时间：{}分钟", 
                    cacheKey, propertyCompanyIds.size(), USER_ROLES_CACHE_EXPIRE);
                return;
                
            } catch (Exception e) {
                log.warn("物业公司缓存设置失败，重试次数：{}/{}，缓存键：{}，错误：{}", 
                    i + 1, CACHE_RETRY_TIMES, cacheKey, e.getMessage());
                
                if (i == CACHE_RETRY_TIMES - 1) {
                    log.error("物业公司缓存设置最终失败，缓存键：{}", cacheKey, e);
                }
            }
        }
    }
    
    
    /**
     * 根据物业公司ID列表获取用户ID列表
     * 
     * @param propertyCompanyIds 物业公司ID列表
     * @return 用户ID列表
     * @throws Exception 统一异常
     */
    @Override
    @Cacheable(value = "property:company:user:ids", key = "#propertyCompanyIds.hashCode()", unless = "#result == null || #result.isEmpty()")
    public List<Long> getUserIdsByPropertyCompanyIds(List<Long> propertyCompanyIds) throws Exception {
        if (propertyCompanyIds == null || propertyCompanyIds.isEmpty()) {
            log.warn("物业公司ID列表为空，无法获取用户ID列表");
            return Collections.emptyList();
        }
        
        log.debug("根据物业公司ID列表获取用户ID列表，物业公司ID列表：{}", propertyCompanyIds);
        
        try {
            // 查询用户物业公司关联表
            LambdaQueryWrapper<UserPropertyCompany> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(UserPropertyCompany::getPropertyCompanyId, propertyCompanyIds)
                       .eq(UserPropertyCompany::getStatus, 1); // 在职状态
            
            List<UserPropertyCompany> userPropertyCompanies = userPropertyCompanyMapper.selectList(queryWrapper);
            
            List<Long> userIds = userPropertyCompanies.stream()
                    .map(UserPropertyCompany::getUserId)
                    .distinct()
                    .collect(Collectors.toList());
            
            log.debug("物业公司范围内的用户ID列表：{}", userIds);
            return userIds;
            
        } catch (Exception e) {
            log.error("根据物业公司ID列表获取用户ID列表失败，物业公司ID列表：{}，错误：{}", propertyCompanyIds, e.getMessage(), e);
            return Collections.emptyList();
        }
    }
} 

